﻿using System;
using System.Runtime.InteropServices;

namespace Eflong.MonitoringLib.Common
{
    public struct MonUnitData
    {
        private const int SIZE_MONUNITID = 9;

        // MonUnitData() { }
        [MarshalAs( UnmanagedType.ByValArray , SizeConst = SIZE_MONUNITID )]
        public char[ ] m_szId;

        //public SYSTEMTIME m_stData;
        //public SYSTEMTIME m_stStateChange;
        public SystemTime m_stData;

        public SystemTime m_stStateChange;
        public byte m_nState;
        public float m_fValue;

        public static int Size( )
        {
            return 48;
        }

        public byte[ ] GetByteArray( )
        {
            int length = Marshal.SizeOf( this );
            byte[ ] ba = new byte[ length ];
            int pos = 0;
            KWConvert.SetCharArrayToByteArray( m_szId , ref ba , ref pos , SIZE_MONUNITID );
            pos++;
            KWConvert.SetUShortToByteArray( m_stData.year , ref ba , ref pos );
            KWConvert.SetUShortToByteArray( m_stData.month , ref ba , ref pos );
            KWConvert.SetUShortToByteArray( m_stData.dayofweek , ref ba , ref pos );
            KWConvert.SetUShortToByteArray( m_stData.day , ref ba , ref pos );
            KWConvert.SetUShortToByteArray( m_stData.hour , ref ba , ref pos );
            KWConvert.SetUShortToByteArray( m_stData.minute , ref ba , ref pos );
            KWConvert.SetUShortToByteArray( m_stData.second , ref ba , ref pos );
            KWConvert.SetUShortToByteArray( m_stData.milliseconds , ref ba , ref pos );
            KWConvert.SetUShortToByteArray( m_stStateChange.year , ref ba , ref pos );
            KWConvert.SetUShortToByteArray( m_stStateChange.month , ref ba , ref pos );
            KWConvert.SetUShortToByteArray( m_stStateChange.dayofweek , ref ba , ref pos );
            KWConvert.SetUShortToByteArray( m_stStateChange.day , ref ba , ref pos );
            KWConvert.SetUShortToByteArray( m_stStateChange.hour , ref ba , ref pos );
            KWConvert.SetUShortToByteArray( m_stStateChange.minute , ref ba , ref pos );
            KWConvert.SetUShortToByteArray( m_stStateChange.second , ref ba , ref pos );
            KWConvert.SetUShortToByteArray( m_stStateChange.milliseconds , ref ba , ref pos );

            KWConvert.SetByteToByteArray( m_nState , ref ba , ref pos );

            // 增加一个

            pos++;
            KWConvert.SetFloatToByteArray( m_fValue , ref ba , ref pos );
            return ba;
        }

        public void Init( )
        {
            m_szId = new char[ SIZE_MONUNITID ];
            m_stData = new SystemTime( );// new SYSTEMTIME();
            m_stStateChange = new SystemTime( );// new SYSTEMTIME();

            //m_stData.wYear = new byte[2];
            //m_stData.wMonth = new byte[2];
            //m_stData.wDayOfWeek = new byte[2];
            //m_stData.wDay = new byte[2];
            //m_stData.wHour = new byte[2];
            //m_stData.wMinute = new byte[2];
            //m_stData.wSecond = new byte[2];
            //m_stData.wMilliseconds = new byte[2];
            //m_stStateChange = new SYSTEMTIME();
            //m_stStateChange.wYear = new byte[2];
            //m_stStateChange.wMonth = new byte[2];
            //m_stStateChange.wDayOfWeek = new byte[2];
            //m_stStateChange.wDay = new byte[2];
            //m_stStateChange.wHour = new byte[2];
            //m_stStateChange.wMinute = new byte[2];
            //m_stStateChange.wSecond = new byte[2];
            //m_stStateChange.wMilliseconds = new byte[2];
        }

        public void ConverFromByteArray( byte[ ] ba , ref int pos )
        {
            Init( );

            KWConvert.GetCharArrayFromByteArray( ba , ref m_szId , ref pos , SIZE_MONUNITID );
            pos++;
            KWConvert.GetSystemTimeFormBytes( ba , ref m_stData , ref pos );
            KWConvert.GetSystemTimeFormBytes( ba , ref m_stStateChange , ref pos );

            //KWConvert.GetByteArrayFromByteArray(ba, ref m_stData.wYear, ref pos, 2);
            //KWConvert.GetByteArrayFromByteArray(ba, ref m_stData.wMonth, ref pos, 2);
            //KWConvert.GetByteArrayFromByteArray(ba, ref m_stData.wDayOfWeek, ref pos, 2);
            //KWConvert.GetByteArrayFromByteArray(ba, ref m_stData.wDay, ref pos, 2);
            //KWConvert.GetByteArrayFromByteArray(ba, ref m_stData.wHour, ref pos, 2);
            //KWConvert.GetByteArrayFromByteArray(ba, ref m_stData.wMinute, ref pos, 2);
            //KWConvert.GetByteArrayFromByteArray(ba, ref m_stData.wSecond, ref pos, 2);
            //KWConvert.GetByteArrayFromByteArray(ba, ref m_stData.wMilliseconds, ref pos, 2);
            //KWConvert.GetByteArrayFromByteArray(ba, ref m_stStateChange.wYear, ref pos, 2);
            //KWConvert.GetByteArrayFromByteArray(ba, ref m_stStateChange.wMonth, ref pos, 2);
            //KWConvert.GetByteArrayFromByteArray(ba, ref m_stStateChange.wDayOfWeek, ref pos, 2);
            //KWConvert.GetByteArrayFromByteArray(ba, ref m_stStateChange.wDay, ref pos, 2);
            //KWConvert.GetByteArrayFromByteArray(ba, ref m_stStateChange.wHour, ref pos, 2);
            //KWConvert.GetByteArrayFromByteArray(ba, ref m_stStateChange.wMinute, ref pos, 2);
            //KWConvert.GetByteArrayFromByteArray(ba, ref m_stStateChange.wSecond, ref pos, 2);
            //KWConvert.GetByteArrayFromByteArray(ba, ref m_stStateChange.wMilliseconds, ref pos, 2);
            m_nState = ba[ pos ];
            pos++;

            // 增加一个

            pos++;
            m_fValue = KWConvert.GetFloatFromByteArray( ba , ref pos );
        }
    };

    public struct MonUnitDataItem
    {
        // MonUnitDataItem() { }

        public bool m_bSuccess;
        public long m_nCoalMineId;
        public MonUnitData m_MonUnitData;

        public byte[ ] GetByteArray( )
        {
            int length = Marshal.SizeOf( this );
            byte[ ] ba = new byte[ length ];

            return ba;
        }

        public void ConverFromByteArray( byte[ ] ba , ref int pos )
        {
            m_bSuccess = KWConvert.GetBooleanFromByteArray( ba , ref pos );
            m_nCoalMineId = KWConvert.GetIntFromByteArray( ba , ref pos );
            pos += 3;
            m_MonUnitData.ConverFromByteArray( ba , ref pos );
        }
    };

    public struct DataAckStruct
    {
        // DataAckStruct() { }
        public uint m_dwMethodType;

        public int m_nMethodAck;
        public uint m_dwBufSize;
        public long m_nCoalMineId;
        public uint m_dwNumOfItems;
        public MonUnitDataItem[ ] m_DataItems;

        public byte[ ] GetByteArray( )
        {
            int length = Marshal.SizeOf( this );
            byte[ ] ba = new byte[ length ];

            return ba;
        }

        public void ConverFromByteArray( byte[ ] ba )
        {
            int pos = 0;
            m_dwMethodType = KWConvert.GetUIntFromByteArray( ba , ref pos );
            m_nMethodAck = KWConvert.GetIntFromByteArray( ba , ref pos );
            m_dwBufSize = KWConvert.GetUIntFromByteArray( ba , ref pos );
            m_nCoalMineId = KWConvert.GetIntFromByteArray( ba , ref pos );
            m_dwNumOfItems = KWConvert.GetUIntFromByteArray( ba , ref pos );
            if ( m_dwNumOfItems >= 600 )
            {
                throw new Exception( "DefinitionAckStruct m_dwNumOfItems>= 600 " );
            }
            m_DataItems = new MonUnitDataItem[ m_dwNumOfItems ];
            for ( int i = 0; i < m_dwNumOfItems; i++ )
            {
                MonUnitDataItem item = new MonUnitDataItem( );
                item.ConverFromByteArray( ba , ref pos );
                m_DataItems[ i ] = item;
            }
        }
    };

    public struct MonUnitItem
    {
        public const int SIZE_MONUNITID = 9;

        // MonUnitItem() { }

        public long m_nCoalMineId;

        [MarshalAs( UnmanagedType.ByValArray , SizeConst = SIZE_MONUNITID )]
        public char[ ] m_szMonUnitId;

        public byte[ ] GetByteArray( )
        {
            int length = Marshal.SizeOf( this );
            byte[ ] ba = new byte[ length ];

            return ba;
        }
    };

    public struct DataQueryStruct
    {
        // DataQueryStruct() { }
        public uint m_dwMethodType;

        public int m_nMethodAck;

        public uint m_dwBufSize;
        public long m_nCoalMineId;
        public uint m_dwNumOfItems;
        public MonUnitItem[ ] m_MonUnitItems;

        public byte[ ] GetByteArray( )
        {
            int length = sizeof( int ) * 4 + sizeof( long ) + sizeof( long ) + MonUnitItem.SIZE_MONUNITID;
            byte[ ] ba = new byte[ length ];
            int pos = 0;
            KWConvert.SetUIntToByteArray( m_dwMethodType , ref ba , ref pos );
            KWConvert.SetIntToByteArray( m_nMethodAck , ref ba , ref pos );
            KWConvert.SetUIntToByteArray( m_dwBufSize , ref ba , ref pos );
            KWConvert.SetLongToByteArray( m_nCoalMineId , ref ba , ref pos );
            KWConvert.SetUIntToByteArray( m_dwNumOfItems , ref ba , ref pos );
            return ba;
        }
    };

    public struct DataUpdateStruct
    {
        // DataUpdateStruct() { }
        public uint m_dwMethodType;

        public int m_nMethodAck;
        public uint m_dwBufSize;
        public long m_nCoalMineId;
        public uint m_dwNumOfData;
        public MonUnitData[ ] m_MonUnitData;

        public static int Size( )
        {
            //Console.WriteLine(5 * 4 + MonUnitData.Size());
            return 68;
        }

        public uint dwBufSize( )
        {
            return ( uint )( DataUpdateStruct.Size( ) + MonUnitData.Size( ) * ( m_dwNumOfData - 1 ) );
        }

        public byte[ ] GetByteArray( )
        {
            m_dwBufSize = dwBufSize( );
            int length = ( int )m_dwBufSize;
            byte[ ] ba = new byte[ length ];
            int pos = 0;
            KWConvert.SetUIntToByteArray( m_dwMethodType , ref ba , ref pos );
            KWConvert.SetIntToByteArray( m_nMethodAck , ref ba , ref pos );
            KWConvert.SetUIntToByteArray( m_dwBufSize , ref ba , ref pos );
            KWConvert.SetUIntToByteArray( ( uint )m_nCoalMineId , ref ba , ref pos );
            KWConvert.SetUIntToByteArray( m_dwNumOfData , ref ba , ref pos );
            for ( int i = 0; i < m_dwNumOfData; i++ )
            {
                KWConvert.SetByteArrayToByteArray( m_MonUnitData[ i ].GetByteArray( ) , ref ba , ref pos , MonUnitData.Size( ) );
            }
            return ba;
        }

        public void ConverFromByteArray( byte[ ] ba )
        {
            int pos = 0;
            m_dwMethodType = KWConvert.GetUIntFromByteArray( ba , ref pos );
            m_nMethodAck = KWConvert.GetIntFromByteArray( ba , ref pos );
            m_dwBufSize = KWConvert.GetUIntFromByteArray( ba , ref pos );
            m_nCoalMineId = KWConvert.GetIntFromByteArray( ba , ref pos );
            m_dwNumOfData = KWConvert.GetUIntFromByteArray( ba , ref pos );
            if ( m_dwNumOfData >= 600 )
            {
                throw new Exception( "DefinitionAckStruct m_dwNumOfItems>= 600 " );
            }
            m_MonUnitData = new MonUnitData[ m_dwNumOfData ];
            for ( int i = 0; i < m_dwNumOfData; i++ )
            {
                MonUnitData item = new MonUnitData( );
                item.ConverFromByteArray( ba , ref pos );
                m_MonUnitData[ i ] = item;
            }
        }
    };
}